package service

import (
	"errors"
	"gin-bms/global"
	"gin-bms/model"
	"gin-bms/model/request"
	"strconv"

	"gorm.io/gorm"
)

//创建一个角色
func CreateRole(r model.SysRole) (err error, roleOut model.SysRole) {
	var role model.SysRole
	if !errors.Is(global.GLOBAL_DB.Where("role_id=?", r.RoleId).First(&role).Error, gorm.ErrRecordNotFound) {
		return errors.New("存在相同角色id"), r
	}
	err = global.GLOBAL_DB.Create(&r).Error
	return err, r
}

//复制一个角色
func CopyRole(info request.SysRoleIn) (err error, roleOut model.SysRole) {
	var role model.SysRole
	if !errors.Is(global.GLOBAL_DB.Where("role_id=?", info.Role.RoleId).First(&role).Error, gorm.ErrRecordNotFound) {
		return errors.New("存在相同角色id"), roleOut
	}
	info.Role.Children = []model.SysRole{}
	err, roleMenus := GetRoleMenus(info.OldRoleId)
	var menus []model.SysMenu
	for _, v := range roleMenus {
		num, _ := strconv.Atoi(v.MenuId)
		v.SysMenu.ID = uint(num)
		menus = append(menus, v.SysMenu)
	}
	info.Role.SysMenus = menus
	err = global.GLOBAL_DB.Create(&info.Role).Error

	paths := GetPolicyPathByRoleId(info.OldRoleId)
	err = UpdateCasbin(info.Role.RoleId, paths)
	if err != nil {
		_ = DeleteRole(&info.Role)
	}
	return err, info.Role
}

//更改一个角色
func UpdateRole(info model.SysRole) (err error, roleOut model.SysRole) {
	err = global.GLOBAL_DB.Where("role_id=?", info.RoleId).First(&model.SysRole{}).Updates(&info).Error
	return err, info
}

//删除角色
func DeleteRole(info *model.SysRole) (err error) {
	if !errors.Is(global.GLOBAL_DB.Where("role_id=?", info.RoleId).First(&model.SysUser{}).Error, gorm.ErrRecordNotFound) {
		return errors.New("此角色有用户正在使用禁止删除")
	}
	if errors.Is(global.GLOBAL_DB.Where("parent_id=?", info.RoleId).First(&model.SysRole{}).Error, gorm.ErrRecordNotFound) {
		return errors.New("此角色存在子角色不允许删除")
	}
	db := global.GLOBAL_DB.Preload("SysMenus").Where("role_id=?", info.RoleId).First(info)
	err = db.Unscoped().Delete(info).Error
	if len(info.SysMenus) > 0 {
		err = global.GLOBAL_DB.Model(info).Association("SysMenus").Delete(info.SysMenus)
	} else {
		err = db.Error
	}
	ClearCasbin(0, info.RoleId)
	return err
}

//获取角色信息
func GetRole(r model.SysRole) (err error, roleOut model.SysRole) {
	var role model.SysRole
	//err =global.GLOBAL_DB.Preload("DataRoleId").Where("role_id=?",r.RoleId).First(&role).Error
	err = global.GLOBAL_DB.Where("role_id=?", r.RoleId).First(&role).Error
	return err, role
}

//分页获取角色数据
func GetRoleList(info request.PageInfo) (err error, roleListOut interface{}, total int64) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	db := global.GLOBAL_DB

	var roles []model.SysRole
	//err = db.Limit(limit).Offset(offset).Preload("DataRoleId").Where("parent_id=0").Find(&roles).Error
	err = db.Limit(limit).Offset(offset).Where("parent_id=0").Find(&roles).Error
	if len(roles) > 0 {
		for k := range roles {
			err = getChildrenRole(&roles[k])
		}
	}
	return err, roles, total
}

//获取子角色
func getChildrenRole(r *model.SysRole) (err error) {
	//err =global.GLOBAL_DB.Preload("DataRoleId").Where("parent_id = ?", r.RoleId).Find(&r.Children).Error
	err = global.GLOBAL_DB.Where("parent_id = ?", r.RoleId).Find(&r.Children).Error
	if len(r.Children) > 0 {
		for k := range r.Children {
			err = getChildrenRole(&r.Children[k])
		}
	}
	return err
}

//菜单和角色绑定
func SetRoleMenu(info *model.SysRole) error {
	var s model.SysRole
	global.GLOBAL_DB.Preload("SysMenus").First(&s, "role_id=?", info.RoleId)
	err := global.GLOBAL_DB.Model(&s).Association("SysMenus").Replace(&info.SysMenus)
	return err
}
